const canvas = document.getElementById('particle-canvas');
const ctx = canvas.getContext('2d');

let width = canvas.width = window.innerWidth;
let height = canvas.height = window.innerHeight;

let particles = [];
let mouse = { x: width / 2, y: height / 2 };
let moving = false;
let stationaryTimer = null;

class Particle {
    constructor(x, y) {
        this.x = x;
        this.y = y;
        this.size = Math.random() * 4 + 1.5;
        this.initialSize = this.size;
        this.speedX = (Math.random() - 0.5) * 1.2;
        this.speedY = (Math.random() - 0.5) * 1.2;
        this.hue = Math.random() * 360;
        this.baseSaturation = 65; // 稍微提高基础饱和度
    }

    update() {
        this.x += this.speedX;
        this.y += this.speedY;
        this.speedX *= 0.985;
        this.speedY *= 0.985;
        // 尺寸衰减：移动时较慢，静止时加速消退，形成“取消特效”效果
        if (this.size > 0.25) {
            this.size -= 0.028; // 移动时
            if (!moving) this.size -= 0.025; // 静止加速衰减
        }
    }

    draw() {
        const lifeRatio = Math.max(0, this.size / this.initialSize);
        const sat = Math.max(25, this.baseSaturation * lifeRatio);   // 略提最低饱和度
        const alpha = Math.pow(lifeRatio, 0.8);                      // 透明度衰减更慢
        ctx.fillStyle = `hsla(${this.hue}, ${sat}%, 60%, ${alpha})`;
        ctx.beginPath();
        ctx.arc(this.x, this.y, this.size, 0, Math.PI * 2);
        ctx.fill();
    }
}

let lastSpawn = null;
const MIN_SPAWN_DIST = 22; // 鼠标每移动至少22px才生成一个粒子，提升稀疏度

function handleParticles() {
    if (moving) {
        if (!lastSpawn) lastSpawn = { x: mouse.x, y: mouse.y };
        const dxm = mouse.x - lastSpawn.x;
        const dym = mouse.y - lastSpawn.y;
        const moved = Math.hypot(dxm, dym);
        if (moved >= MIN_SPAWN_DIST) {
            particles.push(new Particle(mouse.x, mouse.y)); // 单点生成，控制密度
            lastSpawn = { x: mouse.x, y: mouse.y };
        }
    }

    for (let i = 0; i < particles.length; i++) {
        particles[i].update();
        particles[i].draw();

        for (let j = i; j < particles.length; j++) {
            const dx = particles[i].x - particles[j].x;
            const dy = particles[i].y - particles[j].y;
            const distance = Math.sqrt(dx * dx + dy * dy);

            if (distance < 85 && moving) { // 降低连线距离阈值，线网更稀疏
                const li = Math.max(0, particles[i].size / particles[i].initialSize);
                const lj = Math.max(0, particles[j].size / particles[j].initialSize);
                const lifeMix = (li + lj) / 2;
                const distFactor = 1 - distance / 85;
                const alpha = Math.max(0, Math.pow(lifeMix, 0.8) * distFactor * 0.9);
                const sat = Math.max(22, 62 * lifeMix);
                const hue = particles[i].hue;

                ctx.beginPath();
                ctx.strokeStyle = `hsla(${hue}, ${sat}%, 62%, ${alpha})`;
                ctx.lineWidth = 0.8 * distFactor;
                ctx.moveTo(particles[i].x, particles[i].y);
                ctx.lineTo(particles[j].x, particles[j].y);
                ctx.stroke();
            }
        }

        if (particles[i].size <= 0.28) {
            particles.splice(i, 1);
            i--;
        }
    }
}

function animate() {
    ctx.clearRect(0, 0, width, height);
    handleParticles();
    requestAnimationFrame(animate);
}

animate();

document.addEventListener('mousemove', e => {
    mouse.x = e.clientX;
    mouse.y = e.clientY;
    moving = true;
    if (stationaryTimer) clearTimeout(stationaryTimer);
    // 鼠标在 220ms 内无移动，则视为静止，自动取消特效
    stationaryTimer = setTimeout(() => { moving = false; }, 220);
});

window.addEventListener('resize', () => {
    width = canvas.width = window.innerWidth;
    height = canvas.height = window.innerHeight;
});

// 更新导航栏渐变位置
(function setupNavFollowGlow(){
    const nav = document.querySelector('nav');
    if (!nav) return;
    const root = document.documentElement;

    function updateVars(e) {
        const rect = nav.getBoundingClientRect();
        const x = e.clientX - rect.left;
        const y = e.clientY - rect.top;
        const px = Math.max(0, Math.min(100, (x / rect.width) * 100));
        const py = Math.max(0, Math.min(100, (y / rect.height) * 100));
        root.style.setProperty('--mx', px + '%');
        root.style.setProperty('--my', py + '%');
    }

    nav.addEventListener('mousemove', updateVars);
    nav.addEventListener('mouseleave', () => {
        root.style.setProperty('--mx', '50%');
        root.style.setProperty('--my', '50%');
    });
})();

// 双图鼠标切换：几何分割线与渐变区域（旧实现，现禁用）
(function dualImageMask(){
    const maskCanvas = document.getElementById('dual-mask-canvas');
    if (!maskCanvas) return;
    const mctx = maskCanvas.getContext('2d');
    const DISABLE_OLD_MASK = true;
    if (DISABLE_OLD_MASK) return;

    function resize() {
        maskCanvas.width = window.innerWidth;
        maskCanvas.height = window.innerHeight;
    }
    resize();
    window.addEventListener('resize', resize);

    // 计算原点(0,0)为导航栏左上角（页面顶部左侧）
    // 实际页面坐标以视口左上角近似作为原点0,0
    const origin = { x: 0, y: 0 };

    let mousePos = { x: window.innerWidth / 2, y: 80 };

    function drawMask() {
        const w = maskCanvas.width;
        const h = maskCanvas.height;
        mctx.clearRect(0,0,w,h);

        // 原点到鼠标连线的方向向量
        const vx = mousePos.x - origin.x;
        const vy = mousePos.y - origin.y;
        const len = Math.hypot(vx, vy) || 1;
        // l2：经过鼠标位置，垂直于原点-鼠标连线
        const nx = -vy / len; // 法线单位向量
        const ny =  vx / len;

        // 直线一般式：n·(p - mouse) = 0 => nx*(x - mx)+ny*(y - my) = 0
        // 距离为 d = nx*(x-mx)+ny*(y-my)
        // 我们让 d<0 的一侧（靠近原点侧）显示图片1，d>0 的一侧显示图片2

        // 计算渐变宽度：页面宽度的 1/3
        const gradWidth = w / 3;

        // 创建两侧的渐变遮罩：
        // 为实现图片切换与过渡，我们绘制一张全屏黑白mask：黑=img1显示，白=img2显示，中间为渐变
        // 简化处理：用合成模式分别绘制两个半透明层
        // 先绘制靠近原点一侧（img1权重更高）
        mctx.save();
        // 整体覆盖填充，随后用渐变沿法线方向叠加
        // 计算每个像素到l2的带符号距离，并用线性函数映射到[0,1]
        // 这里用Canvas的渐变替代像素级计算：沿法线方向创建线性渐变
        const gx = mousePos.x + nx * gradWidth;
        const gy = mousePos.y + ny * gradWidth;
        const gx2 = mousePos.x - nx * gradWidth;
        const gy2 = mousePos.y - ny * gradWidth;
        const grad1 = mctx.createLinearGradient(gx2, gy2, gx, gy); // 从远离原点到靠近原点
        grad1.addColorStop(0, 'rgba(0,0,0,1)');   // 远离原点侧 -> img2
        grad1.addColorStop(0.5, 'rgba(0,0,0,0.5)');
        grad1.addColorStop(1, 'rgba(0,0,0,0)');   // 靠近原点侧 -> img1
        mctx.fillStyle = grad1;
        mctx.fillRect(0,0,w,h);
        mctx.restore();

        // 再绘制远离原点一侧（img2权重更高）
        mctx.save();
        const grad2 = mctx.createLinearGradient(gx, gy, gx2, gy2); // 反向渐变
        grad2.addColorStop(0, 'rgba(255,255,255,1)'); // 远离原点侧 -> img2
        grad2.addColorStop(0.5, 'rgba(255,255,255,0.5)');
        grad2.addColorStop(1, 'rgba(255,255,255,0)'); // 靠近原点侧 -> img1
        mctx.fillStyle = grad2;
        mctx.globalCompositeOperation = 'lighter';
        mctx.fillRect(0,0,w,h);
        mctx.restore();

        // 把mask应用到顶部图片，通过CSS混合效果实现
        // 这里策略：改变顶部图片的不透明度，用mask强弱决定显示比例
        // 简化方案：根据距离符号，计算鼠标所在侧的整体权重，顶图透明度随之变化
        // 为了实现更符合需求的两侧同时显示，我们改为剪裁路径：沿l2把两侧分别绘制
    }

    function applyClip() {
        const w = maskCanvas.width;
        const h = maskCanvas.height;
        mctx.clearRect(0,0,w,h);

        const vx = mousePos.x - origin.x;
        const vy = mousePos.y - origin.y;
        const len = Math.hypot(vx, vy) || 1;
        const nx = -vy / len;
        const ny =  vx / len;

        // 线的点角形式：通过鼠标点，方向为法线(n)
        // 找到l2与画布边界的交点，构造分割多边形
        function lineIntersections(mx,my,dx,dy,w,h){
            const pts = [];
            const edges = [
                {x1:0,y1:0,x2:w,y2:0},
                {x1:w,y1:0,x2:w,y2:h},
                {x1:w,y1:h,x2:0,y2:h},
                {x1:0,y1:h,x2:0,y2:0}
            ];
            edges.forEach(e=>{
                const denom = (dx*(e.y1-e.y2) + dy*(e.x2-e.x1));
                if (Math.abs(denom) < 1e-6) return;
                const t = ((mx - e.x1)*(e.y1 - e.y2) + (my - e.y1)*(e.x2 - e.x1)) / denom;
                const u = ((mx - e.x1)*dy - (my - e.y1)*dx) / denom; // not used
                const x = mx + dx * t;
                const y = my + dy * t;
                if (x>=0 && x<=w && y>=0 && y<=h) pts.push({x,y});
            });
            // 取两端点
            if (pts.length>=2) return [pts[0], pts[1]];
            return null;
        }

        const seg = lineIntersections(mousePos.x, mousePos.y, nx, ny, w, h);
        if (!seg) return;
        const [p1, p2] = seg;

        // 根据l2两侧构造两个多边形区域：使用半平面裁剪（这里用路径约束）
        // 区域A：靠近原点侧 -> img1
        mctx.save();
        mctx.beginPath();
        mctx.moveTo(origin.x, origin.y);
        mctx.lineTo(p1.x, p1.y);
        mctx.lineTo(p2.x, p2.y);
        mctx.lineTo(origin.x, h); // 包括整个靠近原点的半平面（粗略扩展）
        mctx.lineTo(0, h);
        mctx.closePath();
        mctx.clip();
        // 渐变靠近线的区域（宽度w/3）
        const gradWidth = w / 3;
        const gx = mousePos.x + nx * gradWidth;
        const gy = mousePos.y + ny * gradWidth;
        const gx2 = mousePos.x - nx * gradWidth;
        const gy2 = mousePos.y - ny * gradWidth;
        const gradA = mctx.createLinearGradient(gx2, gy2, gx, gy);
        gradA.addColorStop(0, 'rgba(0,0,0,1)');
        gradA.addColorStop(1, 'rgba(0,0,0,0)');
        mctx.fillStyle = gradA;
        mctx.fillRect(0,0,w,h);
        mctx.restore();

        // 区域B：远离原点侧 -> img2
        mctx.save();
        mctx.beginPath();
        mctx.moveTo(w, h);
        mctx.lineTo(p2.x, p2.y);
        mctx.lineTo(p1.x, p1.y);
        mctx.lineTo(w, 0);
        mctx.lineTo(0, 0);
        mctx.closePath();
        mctx.clip();
        const gradB = mctx.createLinearGradient(gx, gy, gx2, gy2);
        gradB.addColorStop(0, 'rgba(255,255,255,1)');
        gradB.addColorStop(1, 'rgba(255,255,255,0)');
        mctx.fillStyle = gradB;
        mctx.fillRect(0,0,w,h);
        mctx.restore();

        // 将遮罩应用到两张图：使用CSS filter调节透明度效果（权重）
        const img1 = document.getElementById('img1');
        const img2 = document.getElementById('img2');
        if (img1 && img2) {
            // 顶层图默认可见，靠近原点侧通过mask使其更透明；背景图相反
            // 简化权重：根据鼠标点到原点的方向，计算一个平滑权重
            const w2 = Math.min(1, Math.hypot(mousePos.x, mousePos.y) / (Math.hypot(w,h)));
            img2.style.opacity = 0.6 + 0.4 * w2; // 距离越远，顶图越明显
            img1.style.opacity = 1 - 0.4 * w2;
        }
    }

    function onMove(e){
        mousePos = { x: e.clientX, y: e.clientY };
        applyClip();
    }

    document.addEventListener('mousemove', onMove);
    applyClip();
})();

// 3D空间投影：多层动画横幅跟随鼠标
(function nav3DFollow(){
    const animatedBanner = document.querySelector('.animated-banner');
    if (!animatedBanner) return;

    const layers = document.querySelectorAll('.animated-banner .layer');
    if (!layers.length) return;

    // 3D空间坐标系统
    const SPACE = {
        origin: { x: 0, y: 0, z: 0 },      // 原点 (0,0,0)
        webPlane: { z: 30 },               // 网页平面 z=30
        mouseZ: 50                         // 鼠标平面 z=50
    };

    let mouse3D = { x: 0, y: 0, z: SPACE.mouseZ };

    function calculate3DProjection(mouseX, mouseY) {
        // 鼠标在3D空间的坐标 (mx, my, 50)
        mouse3D.x = mouseX;
        mouse3D.y = mouseY;

        // 计算从原点(0,0,0)到鼠标(mx,my,50)的连线L1
        // 参数方程: P(t) = t * (mx, my, 50)
        // 求L1与网页平面z=30的交点：t * 50 = 30 => t = 30/50 = 0.6
        const t = SPACE.webPlane.z / SPACE.mouseZ; // t = 30/50 = 0.6
        
        // 投影点在网页平面的坐标
        const projectionPoint = {
            x: t * mouse3D.x,  // 0.6 * mx
            y: t * mouse3D.y   // 0.6 * my
        };

        return projectionPoint;
    }

    function updateNavBackground(projectionPoint) {
          const header = document.querySelector('header');
          if (!header) return;

          const headerRect = header.getBoundingClientRect();
          const centerX = headerRect.width / 2;

          // 计算图片中心应该移动到的位置
            // 只在x轴（横向）应用移动，y轴保持固定
            const offsetX = (projectionPoint.x - centerX) * 0.1; // 缩放因子调整为0.1，减少移动幅度

          // 对每一层应用不同的移动幅度，创造视差效果
          layers.forEach((layer, index) => {
              const layerOffset = offsetX * (1 + index * 0.1); // 每层递增10%的移动幅度
              layer.style.transform = `translateX(${layerOffset}px)`;
          });
      }

      function onMouseMove(e) {
          const header = document.querySelector('header');
          if (!header) return;

          const headerRect = header.getBoundingClientRect();
          
          // 检查鼠标是否在导航栏范围内
          const isInNavBar = e.clientX >= headerRect.left && 
                            e.clientX <= headerRect.right && 
                            e.clientY >= headerRect.top && 
                            e.clientY <= headerRect.bottom;

          if (isInNavBar) {
              // 鼠标在导航栏内，计算3D投影点并跟随
              const mouseX = e.clientX;
              const mouseY = e.clientY;
              const projectionPoint = calculate3DProjection(mouseX, mouseY);
              updateNavBackground(projectionPoint);
          } else {
              // 鼠标移出导航栏，图片归中
              resetToCenter();
          }
      }

      function resetToCenter() {
          // 所有层丝滑归中
          layers.forEach(layer => {
              layer.style.transform = `translateX(0px)`;
          });
      }
 
      // 监听全局鼠标移动
      document.addEventListener('mousemove', onMouseMove);

     // 初始化位置 - 确保图片居中
      const initialProjection = calculate3DProjection(window.innerWidth / 2, window.innerHeight / 2);
      updateNavBackground(initialProjection);
})();

// 滚动动效
(function scrollAnimations() {
    // 滚动监听器
    function handleScrollAnimations() {
        const elements = document.querySelectorAll('.scroll-animate, .feature-card, .stat-item, .testimonial-card');
        
        elements.forEach(element => {
            const elementTop = element.getBoundingClientRect().top;
            const elementVisible = 150;
            
            if (elementTop < window.innerHeight - elementVisible) {
                element.classList.add('animate');
            }
        });
    }

    // 数字计数动画
    function animateNumbers() {
        const statNumbers = document.querySelectorAll('.stat-number');
        
        statNumbers.forEach(stat => {
            const target = parseInt(stat.getAttribute('data-target'));
            const increment = target / 100;
            let current = 0;
            
            const timer = setInterval(() => {
                current += increment;
                if (current >= target) {
                    current = target;
                    clearInterval(timer);
                }
                stat.textContent = Math.floor(current);
            }, 20);
        });
    }

    // 监听滚动事件
    window.addEventListener('scroll', handleScrollAnimations);
    
    // 页面加载时检查一次
    document.addEventListener('DOMContentLoaded', () => {
        handleScrollAnimations();
        
        // 当数据统计区域进入视野时启动数字动画
        const statsSection = document.querySelector('.stats-section');
        if (statsSection) {
            const observer = new IntersectionObserver((entries) => {
                entries.forEach(entry => {
                    if (entry.isIntersecting) {
                        animateNumbers();
                        observer.unobserve(entry.target);
                    }
                });
            }, { threshold: 0.5 });
            
            observer.observe(statsSection);
        }
    });

    // 平滑滚动
    document.querySelectorAll('a[href^="#"]').forEach(anchor => {
        anchor.addEventListener('click', function (e) {
            e.preventDefault();
            const target = document.querySelector(this.getAttribute('href'));
            if (target) {
                target.scrollIntoView({
                    behavior: 'smooth',
                    block: 'start'
                });
            }
        });
    });
})();